

class SocketChannel(object):
    __slots__ = ["_sock", "_buf"]
    MAX_CHUNK = 8000
    def __init__(self, sock):
        self._sock = sock
        self._buf = ""
    def close(self):
        self._sock.close()
    def send(self, data):
        data2 = data.encode("hex") + "\n"
        while data2:
            sent = self._sock.send(data2[:self.MAX_CHUNK])
            data2 = data2[sent:]
    def recv(self):
        while True:
            nl = self._buf.find("\n")
            if nl > 0:
                break
            data = self._sock.recv(self.MAX_CHUNK)
            if not data:
                raise EOFError()
            self._buf += data
        data = self._buf[:nl]
        self._buf = self._buf[nl + 1:]
        return data.decode("hex")
    def expect(self, data):
        data2 = self.recv()
        if data2 != data:
            raise ValueError("excpeted %r, found %r" % (data, data2))

